package cn.turboinfo.fuyang.api.provider.common.service.impl.spec;

import cn.turboinfo.fuyang.api.domain.common.service.spec.SpecService;
import cn.turboinfo.fuyang.api.entity.common.pojo.spec.Spec;
import cn.turboinfo.fuyang.api.provider.common.repository.database.spec.SpecDAO;
import cn.turboinfo.fuyang.api.provider.common.repository.database.spec.SpecPO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sunshow.toolkit.core.qbean.helper.service.impl.DefaultQServiceImpl;
import nxcloud.foundation.core.data.support.annotation.EnableSoftDelete;
import nxcloud.foundation.core.util.TreeHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.Comparator;
import java.util.List;

@Slf4j
@RequiredArgsConstructor
@EnableSoftDelete
@Service
public class SpecServiceImpl extends DefaultQServiceImpl<Spec, Long, SpecPO, SpecDAO> implements SpecService {

    @SuppressWarnings("unchecked")
    private List<Spec> buildTree(List<Spec> specList) {
        return TreeHelper.buildTree(
                specList,
                Spec::getId,
                Spec::getParentId,
                (spec, children) -> {
                    spec.setChildren((List<Spec>) children);
                    return null;
                },
                Comparator.comparing(Spec::getSortValue)
        );
    }

    @Override
    public List<Spec> findAllSortedWithHierarchy() {
        return buildTree(convertQBeanToList(dao.findAll()));
    }


    @Override
    public List<Spec> findWithHierarchy(Collection<Long> specSetIdCollection) {
        return buildTree(convertQBeanToList(dao.findAllBySpecSetIdInOrderBySortValueDescIdAsc(specSetIdCollection)));
    }

    @Override
    public List<Spec> findBySpecSetIdWithHierarchy(Long specSetId) {
        return findWithHierarchy(List.of(specSetId));
    }

    @Override
    public List<Spec> findByParentIdAndName(Long parentId, String name) {
        return convertQBeanToList(dao.findByParentIdAndNameOrderByIdDesc(parentId, name));
    }

    @Override
    public List<Spec> findByParentId(Long parentId) {
        return convertQBeanToList(dao.findByParentId(parentId));
    }

    @Override
    public boolean checkAvailable(Long parentId, String name) {
        return checkAvailable(null, parentId, name);
    }

    @Override
    public boolean checkAvailable(Long specId, Long parentId, String name) {
        return findByParentIdAndName(parentId, name)
                .stream()
                .allMatch(it -> it.getId().equals(specId));
    }

    @Override
    @Transactional
    public void deleteById(Long id) {
        // 查询规格
        Spec spec = getByIdEnsure(id);
        if (spec.getParentId() == 0) {
            List<SpecPO> specList = dao.findByParentId(spec.getId());
            for (SpecPO it : specList) {
                super.deleteById(it.getId());
            }
        }
        super.deleteById(id);
    }
}
